package com.zhanghe.study.springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCommands;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

//redis锁机制测试
@RestController
@RequestMapping(value = "/redis")
public class RedisController {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @RequestMapping("/test1")
    public String testRedis(){
        String id = UUID.randomUUID().toString();
        // 设置值
        stringRedisTemplate.opsForValue().setIfAbsent(id,"value");
        System.out.println(id);
        // 模拟故障，导致过期时间没有设置成功，此key就变成永不过期了
        int i = 1/0;
        // 设置过期时间
        stringRedisTemplate.expire(id,30, TimeUnit.SECONDS);
        try {
            // 线程睡眠10s中来模拟业务操作
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //释放锁
        stringRedisTemplate.delete(id);
        return "success";
    }

    @RequestMapping("/test2")
    public String testRedis2(){
        String id = UUID.randomUUID().toString();
        System.out.println(id);
        // 设置值，由于redisTemplate不存在同时进行设置值以及设置过期时间
        // 可以使用jedis原生连接，可以进行原子操作
        stringRedisTemplate.execute((RedisCallback<Object>) connection -> {
            JedisCommands jedisCommands = (JedisCommands) connection.getNativeConnection();
            //NX|XX, NX -- Only set the key if it does not already exist. XX -- Only set the key if it already exist.
            //EX|PX, expire time units: EX = seconds; PX = milliseconds
            if(jedisCommands instanceof Jedis){

            }
            return jedisCommands.set(id,"value","NX","PX",30000);
        });

        try {
            // 线程睡眠10s中来模拟业务操作
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //释放锁
        stringRedisTemplate.delete(id);
        return "success";
    }
//    @Autowired
//    UserRedis userRedis;
//    @Autowired
//    DepartmentRepository departmentRepository;
//    @Autowired
//    UserRepository userRepository;
//    @Autowired
//    RoleRepository roleRepository;

//    @RequestMapping("/addUser")
//    public Object addUser(){
//        initData();
//        User user = userRepository.findOne(userRepository.findAll().get(0).getId());
//        String key = UUID.randomUUID().toString();
//        Long time = 10L;
//        userRedis.add(key,time,user);
//        return "success";
//    }
//
//        userRepository.deleteAll();
//        departmentRepository.deleteAll();
//        roleRepository.deleteAll();
//
//
//        Department department = new Department();
//        department.setName("IT部");
//        departmentRepository.save(department);
//
//        Role role = new Role();
//        role.setName("admin");
//        roleRepository.save(role);
//
//        List<Role> roles = new ArrayList<>();
//        roles.add(role);
//        User user = new User();
//        user.setName("张三");
//        user.setCreatedate(new Date());
//        user.setDepartment(department);
//        user.setRoles(roles);
//        userRepository.save(user);
//    }

//    private void initData(){


    public static void main(String[] args) {
        RedisController redisController = new RedisController();

        List<Long> creativeIds = new ArrayList<>();
        creativeIds.add(100L);
        creativeIds.add(101L);
        creativeIds.add(102L);

        Long lastCreative = redisController.getLastCreative("uid", "dealId");
        System.out.println(lastCreative);
        if(lastCreative == null){ // 第一次曝光
            Long crativeId = creativeIds.get(0);
            // 曝光操作 doSomething
            redisController.addExpose("uid","dealId",crativeId);
        } else { // 不是第一次曝光
            int lastIndex = 0;
            for(int i = 0;i<creativeIds.size();i++){
                if(creativeIds.get(i).equals(lastCreative)){
                    lastIndex = i;
                    break;
                }
            }
            int index = (lastIndex + 1) % creativeIds.size();
            Long crativeId = creativeIds.get(index);
            // 曝光操作 doSomething
            redisController.addExpose("uid","dealId",crativeId);
        }

    }
    Jedis jedis = new Jedis();

    private void addExpose(String uid, String campaignId){
        String key = uid+":"+campaignId;
        jedis.lpush(key, String.valueOf(System.currentTimeMillis()));
    }

    private boolean isOver(String uid, String campaignId, long range,int limit) {
        String key = uid+":"+campaignId;
        long cur = System.currentTimeMillis();

        List<String> exposes = jedis.lrange(key, 0, 10);//最大为10

        int count = 0;
        if (exposes == null || exposes.isEmpty()) {
            return false;
        } else {
            for (String expose: exposes) {
                long time = Long.parseLong(expose);
                if (time > cur - range) {
                    count++;
                } else {
                    break;
                }
            }
        }
        return count > limit;
    }


    private void addExpose(String uid, String deal,long creativeId){
        String key = uid+":"+deal;
        jedis.lpush(key, String.valueOf(creativeId));
    }

    private Long getLastCreative(String uid, String deal) {
        String key = uid+":"+deal;

        // 取最后一条
        String creativeId = jedis.lindex(key, 0);

        if (creativeId == null || creativeId.isEmpty()) {
            return null;
        } else {
            return Long.parseLong(creativeId);
        }
    }




}
